package com.lhd.tool;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import com.lhd.bean.Colinfo;
import lombok.extern.slf4j.Slf4j;
/**
 * 类 {@code Tool} 写入文件攻击.
 *
 * <p>
 * 将表的一行测试数据写入文件
 *
 * @author MapLover
 * @since 2020.09
 */
@Slf4j
public class Tool {

    private static NumberTool genNum = new NumberTool();
    private static StringTool genStr = new StringTool();
    private static DateTool genDate = new DateTool();

    private final BufferedWriter bwriter;

    private static List<Colinfo> clist;

    public Tool(List<Colinfo> clist, String fileName) throws IOException {
        Tool.clist = clist;
        this.bwriter = new BufferedWriter(new FileWriter(new File(fileName), true));
    }

    private synchronized static String GenStr(Colinfo c, int ti) {
        String line = "";

        switch (c.getRule()) {

            case "PHONENO":

                line += genNum.getPhoneNumber() + ",";
                break;

            case "SEX":

                line += genStr.getSex() + ",";
                break;

            case "ID":

                // line += genNum.getRandomNumber(c.DATA_LENGTH) + ",";
                line += genStr.lpad(String.valueOf(ti), 2, "0") + ",";
                break;

            case "NO":

                line += genStr.getRandomNumber(c.getDataLength()) + ",";
                break;

            case "NAME":

                line += genStr.getRandomString(c.getDataLength()) + ",";
                break;

            case "DATE":

                line += genStr.getRandomString(c.getDataLength()) + ",";
                break;

            case "SEQ":

                line += genStr.lpad(String.valueOf(ti), 2, "0") + genStr.getSeqnumeric(c.getDataLength() - 2) + ",";
                break;

            case "CCY"://币种

                line += "01,";// 默认RMB
                break;

            default:
                line += genStr.getRandomAlphanumeric(c.getDataLength()) + ",";

        }
        return line;
    }

    private synchronized static String GenNum(Colinfo c) {
        String line = "";

        switch (c.getRule()) {
            case "BIRTH":
                line += genNum.getGaussRandomNumber(45) + ",";
                break;

            case "DATE":
                line += genDate.getRandomDate() + ",";
                break;

            case "AMT":
                line += genNum.getRandomAmt(c.getDataPrecision(), c.getDataScale()) + ",";
                break;

            case "RAT":
                line += genNum.getRandomRate(c.getDataScale()) + ",";
                break;

            default:
                line += genNum.getRandomNumber(1) + ",";

        }
        return line;

    }

    /**
     * @param clist 该表的所有列信息
     * @param ti    线程数(并发数)
     * @return 一行测试数据
     */
    public synchronized static String GenRow(List<Colinfo> clist, int ti) {

        String line = "";

        for (int i = 0; i < clist.size(); i++) {

            Colinfo c = (Colinfo) clist.get(i);

            switch (c.getDataType()) {
                case "VARCHAR2":
                    line += GenStr(c, ti);
                    continue;
                case "CHAR":
                    line += GenStr(c, ti);
                    continue;
                case "NUMBER":
                    line += GenNum(c);
                    continue;
                case "DATE":
                    line += genDate.getRandomDate() + ",";
                    continue;
            }
        }
        // System.out.print(line);
        line = line.substring(0, line.lastIndexOf(","));

        return line;

    }

    /**
     * @param fileName  待写入文件名
     * @param threadNum 写入并发数(线程数)
     * @param threadNo  第几个线程
     * @param totalRows  该表要生成的行数
     */
    public synchronized void SaveAsBufferWriter(String fileName, int threadNum,int threadNo, int totalRows) {
        try {
            int avgRows = totalRows / threadNum;
            for (int i = 1; i <= avgRows; i++) {
                String line = Tool.GenRow(clist, threadNo) + "\n";

                bwriter.write(line);
                bwriter.flush();

                if (i % 5000 == 0) {
                    log.info(Thread.currentThread().getName() + " Write " + i + " rows!");
                }

            }
            bwriter.close();
            log.info(Thread.currentThread().getName() + " ------------------------closed");
        } catch (IOException e) {
            log.error("text");
            log.error(e.getMessage());
        }
    }
}
